package com.manli.common.utils;

import java.util.Map.Entry;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 微信签名工具类
 * @author Shensg
 *
 * 2020年4月9日
 */
public class WeChatSignUtils {
	/**
	 * 将集合M内非空参数值的参数按照参数名ASCII码从小到大排序（字典序），
	 * 使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串stringA
	 * @param sortedMap
	 * @return
	 */
	public static String getASCII(Map<String, String> map ,List<String> ignorKey) {
		SortedMap<String, Object> sortedMap = new TreeMap<>();
		for (Entry<String, String> entrySet : map.entrySet()) {
			sortedMap.put(entrySet.getKey(), entrySet.getValue());
        }
		String retString = "";
		for (Entry<String, Object> entrySet : sortedMap.entrySet()) {
            if(entrySet.getValue() != null && !ignorKey.contains(entrySet.getKey())) {
            	retString+=entrySet.getKey()+"="+entrySet.getValue()+"&";
            }
        }
		return retString.substring(0,retString.length()-1);
	}
	/**
	 * 在asciiStr最后拼接上key得到stringSignTemp字符串，
	 * 并对stringSignTemp进行MD5运算，
	 * 再将得到的字符串所有字符转换为大写，得到sign值signValue。
	 * @param asciiStr
	 * @param key
	 * @return
	 */
	public static String getSign(String asciiStr , String key) {
		String retString = asciiStr + "&key="+key;
		retString = MD5FileUtil.getMD5String(retString).toUpperCase();
		return retString;
	}
	
	
	/**
	 * 获取微信jssdk注入jssdk config sign
	 * @param noncestr
	 * @param jsapi_ticket
	 * @param timestamp
	 * @param url
	 * @return
	 */
	public static String getsig(String noncestr, String jsapi_ticket, String timestamp, String url) {
		String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp,
				"noncestr=" + noncestr, "url=" + url };
		Arrays.sort(paramArr);
		// 将排序后的结果拼接成一个字符串
		String content = paramArr[0].concat("&" + paramArr[1]).concat("&" + paramArr[2]).concat("&" + paramArr[3]);
		String gensignature = null;
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-1");
			// 对拼接后的字符串进行 sha1 加密
			byte[] digest = md.digest(content.toString().getBytes());
			gensignature = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		// 将 sha1 加密后的字符串与 signature 进行对比
		if (gensignature != null) {
			return gensignature;// 返回signature
		} else {
			return "false";
		}
	}
	
	/**
	 * 微信jsApi支付 签名
	 * @param noncestr
	 * @param jsapi_ticket
	 * @param timestamp
	 * @param url
	 * @return
	 */
	public static String getsigForWxPayMD5(String appId , String timestamp, String noncestr, String packageStr, String signType ,String key) {
		String[] paramArr = new String[] { "appId=" + appId, "timeStamp=" + timestamp,
				"nonceStr=" + noncestr, "package=" + packageStr , "signType=" + signType };
		Arrays.sort(paramArr);
		// 将排序后的结果拼接成一个字符串
		String content = paramArr[0].concat("&" + paramArr[1]).concat("&" + paramArr[2]).concat("&" + paramArr[3]).concat("&" + paramArr[4]);
		content+="&key="+key;
		String gensignature = null;
		gensignature = MD5FileUtil.getMD5String(content.toString().getBytes()).toUpperCase();
		// 将 sha1 加密后的字符串与 signature 进行对比
		if (gensignature != null) {
			return gensignature;// 返回signature
		} else {
			return "false";
		}
	}

	public static String getSha1(TreeMap<String,String> map) throws Exception{
		String str = "";
		for(String value : map.values()){
			str += value;
		}

		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'a', 'b', 'c', 'd', 'e', 'f' };
		MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
		mdTemp.update(str.getBytes("UTF-8"));
		byte[] md = mdTemp.digest();
		int j = md.length;
		char buf[] = new char[j * 2];
		int k = 0;
		for (int i = 0; i < j; i++) {
			byte byte0 = md[i];
			buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
			buf[k++] = hexDigits[byte0 & 0xf];
		}
		return new String(buf);
	}

	/**
	 * 将字节数组转换为十六进制字符串
	 *
	 * @param byteArray
	 * @return
	 */
	private static String byteToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
			strDigest += byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}

	/**
	 * 将字节转换为十六进制字符串
	 *
	 * @param mByte
	 * @return
	 */
	private static String byteToHexStr(byte mByte) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
				'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
		tempArr[1] = Digit[mByte & 0X0F];
		String s = new String(tempArr);
		return s;
	}
	public static void main(String[] args) throws Exception{
//		Map<String, String> sortedMap = new HashMap<>();
//		sortedMap.put("b", "b");
//		sortedMap.put("a", "a");
//		System.out.println(getASCII(sortedMap,Arrays.asList(new String[]{"xml","2"})));
//		System.out.println(getSign("123","2"));

//		System.out.println(getSha1("12314300000000CASHIpK_1T69hDhZkLQTlwsAX2hXbOw84RpmmWM5TTiw9J06QmQDgHrIC67mE_FeBzNdDe7LqsuLFASjN5nw-MrHkgwx3745551a988274db"));
	}
}
